package com.czy.booktest02.demos.service.impl;

import com.czy.booktest02.demos.common.dtos.ResponseResult;
import com.czy.booktest02.demos.common.enums.AppHttpCodeEnum;
import com.czy.booktest02.demos.common.redis.CacheService;
import com.czy.booktest02.demos.common.redis.RedisKey;
import com.czy.booktest02.demos.constant.LockKey;
import com.czy.booktest02.demos.constant.ResultStatus;
import com.czy.booktest02.demos.exception.GlobalException;
import com.czy.booktest02.demos.mapper.BookMapper;
import com.czy.booktest02.demos.mapper.OrderDetailMapper;
import com.czy.booktest02.demos.mapper.OrderMapper;
import com.czy.booktest02.demos.mapper.ShoppingCartMapper;
import com.czy.booktest02.demos.pojo.bo.AccountUserBo;
import com.czy.booktest02.demos.pojo.dto.OrderDto;
import com.czy.booktest02.demos.pojo.po.*;
import com.czy.booktest02.demos.pojo.vo.OrderDetailVO;
import com.czy.booktest02.demos.service.OrderService;
import com.czy.booktest02.demos.service.ShoppingCartService;
import com.czy.booktest02.demos.utils.BaseUtils;
import com.czy.booktest02.demos.utils.ThreadPoolUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    CacheService cacheService;
    @Autowired
    RedissonClient redisson;
    @Autowired
    ShoppingCartMapper shoppingCartMapper;
    @Autowired
    BookMapper bookMapper;
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    OrderDetailMapper orderDetailMapper;
    @Autowired
    ShoppingCartService shoppingCartService;
    @Override
    public ResponseResult commitOrder(OrderDto orderDto) {
        Map<String, Object> map = cacheService.getMap(RedisKey.BOOK_STOCK);
        List<Integer> cartIdList = orderDto.getCartIdList();
        List<ShoppingCart> shoppingCartList=new ArrayList<>();
        for (Integer id : cartIdList) {
            ShoppingCart shoppingCart = shoppingCartMapper.selectById(id);
            shoppingCartList.add(shoppingCart);
            String bookId = String.valueOf(shoppingCart.getBookId());
            if(map.containsKey(bookId)){
                int stock = (Integer) map.get(bookId);
                if(stock<shoppingCart.getQuantity()){
                    //存在一个购物车项库存不足
                    int bookLimitId = shoppingCart.getBookId();
                    Books book = bookMapper.selectById(bookLimitId);
                    return ResponseResult.errorResult(AppHttpCodeEnum.FAILURE,book.getTitle()+"库存不足");
                }
            }
        }
        //所有库存的满足
        ThreadPoolUtils.putOperationToThread(()->{
            //创建锁对象
            RLock lock = redisson.getLock(LockKey.LOCK_KEY);
            try{
                //加锁
                lock.lock();
                Order order = BaseUtils.copyProperties(orderDto, Order.class);
                order.setOrderDate(new Date());
                order.setUserId(AccountUserBo.getUser().getUserId());
                order.setOrderNumberId(UUID.randomUUID().toString());
                //生成订单
                int orderId = orderMapper.createOrder(order);
                //订单详情
                for (ShoppingCart shoppingCart : shoppingCartList) {
                    OrderDetail orderDetail = new OrderDetail();
                    orderDetail.setPrice(shoppingCart.getPrice());
                    orderDetail.setOrderId(orderId);
                    int quantity = shoppingCart.getQuantity();
                    orderDetail.setQuantity(quantity);
                    int bookId = shoppingCart.getBookId();
                    orderDetail.setBookId(bookId);
                    orderDetailMapper.insert(orderDetail);

                    //对应书籍减出售数量
                    bookMapper.updateStock(bookId, quantity);
                }
                //删除购物车项
                shoppingCartService.deleteCartItem(cartIdList);


            }catch (GlobalException e){
                log.print(e.toString());
                throw new GlobalException(ResultStatus.HTTPSERVER_SYSTEM_EXCEPTION,"提交订单失败");
            }finally {
                //释放锁
                lock.unlock();
            }
        });

        //更新缓存
        List<Books> books = bookMapper.selectStock();
        map.clear();
        for (Books book : books) {
            map.put(String.valueOf(book.getId()),book.getStock());
        }
        cacheService.setMap(RedisKey.BOOK_STOCK,map);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult showOrder() {
        List<Order> orders=null;
        //管理员
        if(AccountUserBo.getUser().getIsAdmin()>0) {
            orders = orderMapper.selectAllOrder();

        }
        else{
            //普通用户
            orders = orderMapper.selectOrderByUserId(AccountUserBo.getUser().getUserId());
        }
        return ResponseResult.okResult(orders);
    }

    @Override
    public ResponseResult sendOrder(int id) {
        if(orderMapper.updateStatusById(id)>0){
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        }
        return ResponseResult.errorResult(AppHttpCodeEnum.FAILURE);
    }

    @Override
    public ResponseResult checkOrderDetail(int id) {
        List<OrderDetailVO> orderDetailVOS = orderDetailMapper.selectDetailById(id);
        if(orderDetailVOS!=null){
            return ResponseResult.okResult(orderDetailVOS);
        }
        return ResponseResult.errorResult(AppHttpCodeEnum.FAILURE);
    }
}
